import { find, Node, v3 } from "cc";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { RoleModelComp } from "./model/RoleModelComp";
import { RoleViewComp } from "./view/RoleViewComp";
import { ViewUtil } from "../../../../extensions/oops-plugin-framework/assets/core/utils/ViewUtil";
import { RoleModelBookComp } from "./model/RoleModelBookComp";
import { RoleStarUpComp } from "./bll/RoleStarUp";
import { RoleModelStarComp } from "./model/RoleModelStarComp";
import { RoleAttributeType, RoleBattleType, RoleModuleType } from "./model/RoleEnum";
import { RoleModelLevelComp } from "./model/RoleModelLevelComp";
import { RoleUpgradeComp } from "./bll/RoleUpgrade";
import { RoleModelSkillComp } from "./model/RoleModelSkillComp";
import { oops } from "db://oops-framework/core/Oops";
import { RoleModelBattleComp } from "./model/RoleModelBattleComp";
import { RoleShieldViewComp } from "./view/RoleShieldViewComp";
import { RoleModelEquipComp } from "./model/RoleModelEquipComp";
/** 
 * 角色实体 
 */
@ecs.register('Role')
export class Role extends ecs.Entity {
    // 数据层
    RoleModel!: RoleModelComp;
    RoleModelEquip!: RoleModelEquipComp;
    RoleModelBook!: RoleModelBookComp;
    RoleModelStar!: RoleModelStarComp;
    RoleModelLevel!: RoleModelLevelComp;
    RoleModelSkill!: RoleModelSkillComp;
    RoleModelBattle!: RoleModelBattleComp;
    // 业务层
    RoleStarUp!: RoleStarUpComp;

    // 视图层
    RoleView!: RoleViewComp;                    // 角色动画
    RoleShieldView!: RoleShieldViewComp;

    protected init() {
        this.addComponents<ecs.Comp>(
            RoleModelComp,
            RoleModelSkillComp,
            RoleModelBookComp,
            RoleModelStarComp,
            RoleModelLevelComp,
            RoleModelBattleComp,
            RoleModelEquipComp,
        );
    }



    /** 加载战场角色 */
    loadByBattle(parent: Node) {
        var node = ViewUtil.createPrefabNode(`game/role/role`);
        this.add(node.getComponent(RoleViewComp)!);
        node.setPosition(v3(0, 0, 0));

        node.parent = parent;
    }
    left() {
        find("content/spine", this.RoleView.node)!.setScale(-0.4, 0.4);
    }
    right() {
        find("content/spine", this.RoleView.node)!.setScale(0.4, 0.4);
    }
    /**
     * 设置角色色数值类型
     * @param type   角色属性类型
     * @param rmt    角色模块类型
     * @param value  当前数值
     */
    setNumericValue(type: RoleAttributeType, rmt: RoleModuleType, value: number) {
        var rn = this.RoleModel.attributes.get(type);
        rn.setValue(rmt, value);
    }
    get atk(): number {
        if (this.RoleModel.table.atk == 1) {
            console
        }
        if (this.RoleModel.roleType == RoleBattleType.Tower) {
            var atk = this.getNumericValue(RoleAttributeType.atk);
            var decoratorAtkRatio = this.getNumericValue(RoleAttributeType.atk_ratio, RoleModuleType.Decorator);
            return Math.round(atk * (1 + decoratorAtkRatio));
        } else
            if (this.RoleModel.table.type == 2) {
                var atk = this.getNumericValue(RoleAttributeType.atk);
                var atkRatio = this.getNumericValue(RoleAttributeType.atk_ratio, RoleModuleType.Base);
                var starAtkRatio = this.getNumericValue(RoleAttributeType.atk_ratio, RoleModuleType.Star);
                var skillAtkRatio = this.getNumericValue(RoleAttributeType.atk_ratio, RoleModuleType.Skill);
                var stageAtkRatio = this.getNumericValue(RoleAttributeType.atk_ratio, RoleModuleType.Stage);
                var tzAtkRatio = this.getNumericValue(RoleAttributeType.atk_ratio, RoleModuleType.Equip_tz);
                var haloAtkRatio = this.getNumericValue(RoleAttributeType.atk_ratio, RoleModuleType.Halo);
                var decoratorAtkRatio = this.getNumericValue(RoleAttributeType.atk_ratio, RoleModuleType.Decorator);
                var qiAtkRatio = this.getNumericValue(RoleAttributeType.atk_ratio, RoleModuleType.Qi);

                return Math.round((atk) * (1 + atkRatio) * (1 + starAtkRatio) *
                    (1 + stageAtkRatio) *
                    (1 + skillAtkRatio) * (1 + tzAtkRatio) *
                    (1 + haloAtkRatio) * (1 + decoratorAtkRatio) *
                    (1 + qiAtkRatio));
            } else {
                var atk = this.getNumericValue(RoleAttributeType.atk);
                var decoratorAtkRatio = this.getNumericValue(RoleAttributeType.atk_ratio, RoleModuleType.Decorator);
                return Math.round(atk * (1 + decoratorAtkRatio));
            }

    }

    get def(): number {
        if (this.RoleModel.roleType == RoleBattleType.Tower) {
            var def = this.getNumericValue(RoleAttributeType.def);
            var decoratorDefRatio = this.getNumericValue(RoleAttributeType.def_ratio, RoleModuleType.Decorator);
            return Math.round(def * (1 + decoratorDefRatio));
        } else if (this.RoleModel.table.type == 2) {
            var def = this.getNumericValue(RoleAttributeType.def);

            var defRatio = this.getNumericValue(RoleAttributeType.def_ratio, RoleModuleType.Base);
            var starDefRatio = this.getNumericValue(RoleAttributeType.def_ratio, RoleModuleType.Star);
            var stageDefRatio = this.getNumericValue(RoleAttributeType.def_ratio, RoleModuleType.Stage);
            var skillDefRatio = this.getNumericValue(RoleAttributeType.def_ratio, RoleModuleType.Skill);
            var tzDefRatio = this.getNumericValue(RoleAttributeType.def_ratio, RoleModuleType.Equip_tz);
            var haloDefRatio = this.getNumericValue(RoleAttributeType.def_ratio, RoleModuleType.Halo);
            var decoratorDefRatio = this.getNumericValue(RoleAttributeType.def_ratio, RoleModuleType.Decorator);
            var qiDefRatio = this.getNumericValue(RoleAttributeType.def_ratio, RoleModuleType.Qi);
            return Math.round((def) * (1 + defRatio) * (1 + starDefRatio) *
                (1 + stageDefRatio) *
                (1 + skillDefRatio) * (1 + tzDefRatio) *
                (1 + haloDefRatio) * (1 + decoratorDefRatio) *
                (1 + qiDefRatio));

        } else {
            var def = this.getNumericValue(RoleAttributeType.def);
            var decoratorDefRatio = this.getNumericValue(RoleAttributeType.def_ratio, RoleModuleType.Decorator);
            return Math.round(def * (1 + decoratorDefRatio));
        }
    }

    // 英雄血量=（基础血量+主公血量+水晶数值血量+装备血量+器数值血量+升级成长）*（1+主公加成)*(1+水晶百分比加成)*(1+套装加成)*(1+器百分比加成)*(1+升阶成长)*(1+升星成长)*(1+群英会科技)*(1+<英雄2或3技能加成>）
    get hp(): number {
        if (this.RoleModel.roleType == RoleBattleType.Tower) {
            var hp = this.getNumericValue(RoleAttributeType.hp);
            var decoratorHpRatio = this.getNumericValue(RoleAttributeType.hp_ratio, RoleModuleType.Decorator);
            return Math.round(hp * (1 + decoratorHpRatio));
        } else if (this.RoleModel.table.type == 2) {
            var hp = this.getNumericValue(RoleAttributeType.hp);

            var hpRatio = this.getNumericValue(RoleAttributeType.hp_ratio, RoleModuleType.Base);
            var starHpRatio = this.getNumericValue(RoleAttributeType.hp_ratio, RoleModuleType.Star);
            var stageHpRatio = this.getNumericValue(RoleAttributeType.hp_ratio, RoleModuleType.Stage);
            var skillHpRatio = this.getNumericValue(RoleAttributeType.hp_ratio, RoleModuleType.Skill);
            var tzHpRatio = this.getNumericValue(RoleAttributeType.hp_ratio, RoleModuleType.Equip_tz);
            var haloHpRatio = this.getNumericValue(RoleAttributeType.hp_ratio, RoleModuleType.Halo);
            var decoratorHpRatio = this.getNumericValue(RoleAttributeType.hp_ratio, RoleModuleType.Decorator);
            var qiHpRatio = this.getNumericValue(RoleAttributeType.hp_ratio, RoleModuleType.Qi);

            return Math.round((hp) * (1 + hpRatio) * (1 + starHpRatio) *
                (1 + stageHpRatio) *
                (1 + skillHpRatio) * (1 + tzHpRatio) *
                (1 + haloHpRatio) * (1 + decoratorHpRatio) *
                (1 + qiHpRatio));

        } else {
            var hp = this.getNumericValue(RoleAttributeType.hp);
            var decoratorHpRatio = this.getNumericValue(RoleAttributeType.hp_ratio, RoleModuleType.Decorator);
            return Math.round(hp * (1 + decoratorHpRatio));
        }
    }

    get spd(): number {
        if (this.RoleModel.roleType == RoleBattleType.Tower) {
            var spd = this.getNumericValue(RoleAttributeType.spd);
            var decoratorSpdRatio = this.getNumericValue(RoleAttributeType.spd_ratio, RoleModuleType.Decorator);
            return Math.round(spd * (1 + decoratorSpdRatio));
        } else if (this.RoleModel.table.type == 2) {
            var spd = this.getNumericValue(RoleAttributeType.spd);

            var spdRatio = this.getNumericValue(RoleAttributeType.spd_ratio, RoleModuleType.Base);
            var starSpdRatio = this.getNumericValue(RoleAttributeType.spd_ratio, RoleModuleType.Star);
            var stageSpdRatio = this.getNumericValue(RoleAttributeType.spd_ratio, RoleModuleType.Stage);
            var tzSpdRatio = this.getNumericValue(RoleAttributeType.spd_ratio, RoleModuleType.Equip_tz);
            var skillSpdRatio = this.getNumericValue(RoleAttributeType.spd_ratio, RoleModuleType.Skill);
            var haloSpdRatio = this.getNumericValue(RoleAttributeType.spd_ratio, RoleModuleType.Halo);
            var decoratorSpdRatio = this.getNumericValue(RoleAttributeType.spd_ratio, RoleModuleType.Decorator);
            var qiSpdRatio = this.getNumericValue(RoleAttributeType.spd_ratio, RoleModuleType.Qi);

            return Math.round((spd) * (1 + spdRatio) * (1 + starSpdRatio) *
                (1 + stageSpdRatio) * (1 + skillSpdRatio) *
                (1 + tzSpdRatio) * (1 + haloSpdRatio) *
                (1 + decoratorSpdRatio) * (1 + qiSpdRatio));
        } else {
            var spd = this.getNumericValue(RoleAttributeType.spd);
            var decoratorSpdRatio = this.getNumericValue(RoleAttributeType.spd_ratio, RoleModuleType.Decorator);
            return Math.round(spd * (1 + decoratorSpdRatio));
        }
    }
    /**
   * 获取角色数值类型
   * @param rat 角色属性类型
   * @param rmt 角色模块类型 - 为空时获取所有模块的和
   * @returns 数值
   */
    getNumericValue(rat: RoleAttributeType, rmt: RoleModuleType = null!): number {
        var rn = this.RoleModel.attributes.get(rat);
        if (rmt == null) {
            return rn.value;
        }
        return rn.getValue(rmt)!;
    }
    /**
  * 删除某一角色模块类型所有属性
  * @param rmt    角色模块类型
  */
    removeAllNumericByType(rmt: RoleModuleType) {
        this.RoleModel.attributes.forEach(rn => {
            rn.setValue(rmt, 0);
        });
    }
    /**
   * 移除角色所有属性修饰器
   */
    removeAllDecorators() {
        this.RoleModel.attributes.removeAllDecorator();
        oops.log.logBusiness(`【移除】角色【${this.RoleModel.table.name}】所有附加属性`);
    }
    /** 初始化设置星星数量 */
    setStar(num: number) {
        // let ru = this.get(RoleStarUpComp);
        // if (!ru) {
        //     ru = this.add(RoleStarUpComp);
        // }let ru
        let ru = this.add(RoleStarUpComp);
        ru.star = num;
        ru.type = 0;
    }
    /** 加载升星成功页面 */
    loadStarUpSuccessPop() {

    }
    setLevel(lv: number) {
        let ru = this.get(RoleUpgradeComp);
        if (!ru) {
            ru = this.add(RoleUpgradeComp);
        }
        ru.lv = lv;
        ru.type = 0;
    }
    /** 检查武将图鉴是否可以领取星星 */
    checkBookStar() {
        //  this.add(RoleBookStarCheckComp);
    }
    /** 加载护盾动画预制体 */
    loadShieldSp() {
        if (this.has(RoleShieldViewComp)) {
            return
        }
        var node = ViewUtil.createPrefabNode(`game/role/shield`);
        this.add(node.getComponent(RoleShieldViewComp)!);
        node.parent = this.RoleView.node;
    }

    removeShield() {
        this.setNumericValue(RoleAttributeType.shield, RoleModuleType.Decorator, 0);
        this?.RoleView?.getComponent(RoleViewComp)?.setHpBar();
        this.remove(RoleShieldViewComp);
    }
    /**
     * 上阵武将位置
     */
    get pos(): number {
        return this.RoleModel.pos;
    }
    /** 设置装备套装属性 */
    setEquipTaozhuang() {
        console.warn("设置装备套装属性 todo");
    }
    destroy(): void {
        this.remove(RoleViewComp);

        super.destroy();
    }
    /** 更新战斗力 */
    refreshZhanli() {
        if (!this.RoleModel.myTeam) {
            return
        }
        if (!this.RoleModel.pos) {
            return
        }
        console.warn("更新战斗力 todo");
        // if (this.has(RoleZhanliBllComp)) {
        //     this.remove(RoleZhanliBllComp)
        // }
        // this.add(RoleZhanliBllComp);
    }
}